package org.chen.aao.file.service;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import org.chen.aao.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.chen.aao.common.file.dto.FileUploadResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class FileService {
    
    @Value("${aliyun.oss.endpoint}")
    private String endpoint;
    
    @Value("${aliyun.oss.access-key-id}")
    private String accessKeyId;
    
    @Value("${aliyun.oss.access-key-secret}")
    private String accessKeySecret;
    
    @Value("${aliyun.oss.bucket-name}")
    private String bucketName;
    
    @Value("${aliyun.oss.domain}")
    private String ossDomain;
    
    private OSS ossClient;
    
    // 允许的音频文件格式
    private static final List<String> ALLOWED_AUDIO_TYPES = Arrays.asList(
            "audio/wav", "audio/mp3", "audio/mpeg", "audio/webm", "audio/ogg"
    );
    
    // 允许的图片格式
    private static final List<String> ALLOWED_IMAGE_TYPES = Arrays.asList(
            "image/jpeg", "image/jpg", "image/png", "image/gif", "image/webp"
    );
    
    // 最大文件大小（字节）
    private static final long MAX_AUDIO_SIZE = 10 * 1024 * 1024; // 10MB
    private static final long MAX_IMAGE_SIZE = 5 * 1024 * 1024;  // 5MB
    
    @PostConstruct
    public void init() {
        ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }
    
    @PreDestroy
    public void destroy() {
        if (ossClient != null) {
            ossClient.shutdown();
        }
    }
    
    public FileUploadResponse uploadAudio(MultipartFile file, Long userId) throws IOException {
        // 验证文件
        validateAudioFile(file);
        
        // 生成文件路径
        String directory = String.format("audio/%d/%s", 
                userId, 
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")));
        
        return uploadFile(file, directory);
    }
    
    public FileUploadResponse uploadImage(MultipartFile file, Long userId) throws IOException {
        // 验证文件
        validateImageFile(file);
        
        // 生成文件路径
        String directory = String.format("images/%d/%s", 
                userId, 
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM")));
        
        return uploadFile(file, directory);
    }
    
    public FileUploadResponse uploadFile(MultipartFile file, String directory) throws IOException {
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;
        String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileName = directory + "/" + UUID.randomUUID() + extension;
        
        InputStream inputStream = file.getInputStream();
        
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(file.getContentType());
        metadata.setContentLength(file.getSize());
        metadata.setCacheControl("max-age=31536000");
        
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    bucketName, fileName, inputStream, metadata);
            
            ossClient.putObject(putObjectRequest);
            
            String fileUrl = ossDomain + "/" + fileName;
            
            return FileUploadResponse.builder()
                    .url(fileUrl)
                    .fileName(fileName)
                    .size(file.getSize())
                    .contentType(file.getContentType())
                    .uploadTime(LocalDateTime.now())
                    .build();
                    
        } catch (Exception e) {
            log.error("OSS upload error: {}", e.getMessage());
            throw new BusinessException("文件上传失败");
        } finally {
            inputStream.close();
        }
    }
    
    public void deleteFile(String fileUrl) {
        try {
            String fileName = fileUrl.replace(ossDomain + "/", "");
            ossClient.deleteObject(bucketName, fileName);
            log.info("File deleted: {}", fileName);
        } catch (Exception e) {
            log.error("OSS delete error: {}", e.getMessage());
        }
    }
    
    private void validateAudioFile(MultipartFile file) {
        if (file.isEmpty()) {
            throw new BusinessException("文件不能为空");
        }
        
        if (!ALLOWED_AUDIO_TYPES.contains(file.getContentType())) {
            throw new BusinessException("不支持的音频格式");
        }
        
        if (file.getSize() > MAX_AUDIO_SIZE) {
            throw new BusinessException("音频文件不能超过10MB");
        }
    }
    
    private void validateImageFile(MultipartFile file) {
        if (file.isEmpty()) {
            throw new BusinessException("文件不能为空");
        }
        
        if (!ALLOWED_IMAGE_TYPES.contains(file.getContentType())) {
            throw new BusinessException("不支持的图片格式");
        }
        
        if (file.getSize() > MAX_IMAGE_SIZE) {
            throw new BusinessException("图片文件不能超过5MB");
        }
    }
}